package com.waimai.app.qa.webdriver;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.ScreenOrientation;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.google.gson.JsonObject;
import com.waimai.app.qa.data.Helper;
import com.waimai.app.qa.util.Base;
import com.waimai.app.qa.util.Logger;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MultiTouchAction;

//import io.appium.java_client.NetworkConnectionSetting;

import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.Connection;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileCapabilityType;

public class AppDriver extends Base{
	
	public static AppiumDriver<WebElement> driver = null;
	
	protected static Helper helper = new Helper();
	
	//public static int implicitlyWait = Integer.parseInt(System.getProperty("AppiumDriver.ImplicitlyWait").trim());
	//public static int driverWait = Integer.parseInt(System.getProperty("AppiumDriveri.DriverWait").trim());
	
	public static int implicitlyWait = 10;
	public static int driverWait = 10;
	public static String deviceid = "";
	
	public static void initDriver() throws Exception{
	
		DesiredCapabilities capabilities = new DesiredCapabilities();
		//设置自动化相关参数
		capabilities.setCapability("platformName",System.getProperty("AppiumDriver.Platform"));
		
		//获取设备ID
		capabilities.setCapability("deviceName",System.getProperty("AppiumDriver.DeviceName"));
		deviceid=getDeviceInfo("adb devices");
		
		if(deviceid.equals("")) {
			Logger.log("device not connected");
			System.exit(1);
		}
		capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, deviceid);
		
		//设置android系统版本
	    capabilities.setCapability("platformVersion",System.getProperty("AppiumDriver.Version"));
		String version=getDeviceInfo("adb shell getprop ro.build.version.release");
		if(version.equals(""))	
		{
			Logger.log("version is null");
			System.exit(1);
		}
		capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, version);
		
		if(System.getProperty("AppiumDriver.Browser") == null){
			File classpathRoot = new File(System.getProperty("user.dir"));
			Logger.log("classpathRoot:" + classpathRoot.toString());
			//设置apk路径
			File appDir = new File(classpathRoot, System.getProperty("AppiumDriver.AppDir"));
			File app = new File(appDir, System.getProperty("AppiumDriver.AppName"));
			capabilities.setCapability("app", app.getAbsolutePath());
			
			Logger.log("##########");
			Logger.log(app.getAbsolutePath());
			Logger.log("##########");
			
			if(System.getProperty("AppiumDriver.Platform").equals("Android")){
				//设置app的主包名和主类名
				capabilities.setCapability("appPackage",System.getProperty("AppiumDriver.Package"));
			    capabilities.setCapability("appActivity",System.getProperty("AppiumDriver.Activity"));
			    capabilities.setCapability("device-ready-timeout",System.getProperty("AppiumDriver.deviceReadyTimeout"));
			    capabilities.setCapability("noReset", true);	//若已安装APP，则不重新安装
			    
		        //support Chinese支持中文输入
			    capabilities.setCapability("unicodeKeyboard",true);
			    //重置输入法为系统默认
			    capabilities.setCapability("resetKeyboard","True");
			    
		        //初始化
			    driver = new AndroidDriver<>(new URL(System.getProperty("AppiumDriver.URL")),capabilities);
			}
			else{
				capabilities.setCapability("device-ready-timeout",System.getProperty("AppiumDriver.launchTimeout"));
				driver = new IOSDriver<>(new URL(System.getProperty("AppiumDriver.URL")),capabilities);
			}
		}
		else{
		    if(System.getProperty("AppiumDriver.Platform").equals("Browser")){
		    	capabilities.setCapability("browserName", System.getProperty("AppiumDriver.Browser"));
		    	driver = new AndroidDriver<WebElement>(new URL(System.getProperty("AppiumDriver.URL")),capabilities);	
			}
			else{
				capabilities.setCapability("browserName", System.getProperty("AppiumDriver.Browser"));
				driver = new IOSDriver<>(new URL(System.getProperty("AppiumDriver.URL")),capabilities);
			}
		}
		Logger.log("设置全局显示等待");	
		driver.manage().timeouts().implicitlyWait(implicitlyWait ,TimeUnit.SECONDS);
	}

	/**
	 * @Description：动态获取deviceId 和 Android系统版本
	 * @author：hyzhao 
	 * @time：2017年6月28日 下午2:19:42
	 */
	
	private static String getDeviceInfo(String cmd) {
//		String command = "/Users/baidu/Library/Android/sdk/platform-tools/" + cmd;//mac下执行，如果在win下执行 注释这句
		String command = "/Users/iwm/Documents/instal/android-sdk-macosx/platform-tools/" + cmd;   //limin的mac执行
		Runtime runtime=Runtime.getRuntime();
		try{
//			Process process =runtime.exec(cmd);//windows下执行
			Process process =runtime.exec(command);//mac下执行
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			String line;
			// 循环读取  
			while ((line = reader.readLine()) != null) {  
		    // 循环写入  
				/*if(line.contains("device")&&(line.split("\t").length>1))
				{
					Logger.log("设备ID：" + line.split("\t")[0]);
					return line.split("\t")[0];
				} else {
					Logger.log("Android系统版本：" + line.split("\t")[0]);
					return line.split("\t")[0];
				}*/
				
				   // 循环写入  
                if(line.contains("device")&&(line.split("\t").length>1)) {
                    System.out.println("设备ID：" + line.split("\t")[0]);
                    return line.split("\t")[0];
                }else {
//					Logger.log("Android系统版本：" + line.split("\t")[0]);
					System.out.println("Android系统版本：" + line.split("\t")[0]);
					return line.split("\t")[0];
				}

		  }  
		   // 关闭输出流  
		   process.getOutputStream().close();
		}catch(Exception e){
			Logger.log(e.toString());
		}
		return null;
	}

	/**
	 * 锁定iOS设备多少秒
	 * @author aihui
	 * @param time
	 */
	public static void lock_IOS_device(int time) {
		((IOSDriver<WebElement>) driver).lockDevice(time);
	}
		
	/**
	 * 判断android设备是否被锁,如果锁住则返回true,反之返回false(只能在 Android设备上使用)
	 * @author aihui
	 * @return true if device is locked. False otherwise
	 */
	public boolean isLocked_AND(){
		return ((AndroidDriver) driver).isLocked();
	}
	
	/**
	 * 锁定android设备
	 * @author aihui
	 */
	public static void lock_AND_device() {
		((AndroidDriver) driver).lockDevice();
	}
	
	/**
	 * 解锁android设备
	 * @author aihui
	 */
	public static void unlock_AND_device() {
		((AndroidDriver) driver).unlockDevice();
	}
	
	/**
	 * 将app置于后台,即当前应用放到后台seconds秒
	 * 与resetApp类似,区别是resetApp关闭后立即启动,而这个方法是关闭后等待seconds秒后再启动
	 * @author aihui
	 * @param time
	 */
	public static void background(int time){
		driver.runAppInBackground(time);
	}
	
	/**
	 * 收起(隐藏)键盘
	 * @author aihui
	 */
	public static void hideKeyboard(){
		driver.hideKeyboard();
	}
		
	/**
	 * 在当前应用中打开一个 activity或者启动一个新应用并打开一个 activity(只能在 android上使用)
	 * Eg: ((AndroidDriver) driver).startActivity("appPackage","com.example.android.apis", null, null);
	 * @author aihui
	 */
	public static void startActivity_AND(String appPackage, String appActivity,String appWaitPackage, String appWaitActivity){
		((AndroidDriver) driver).startActivity(appPackage,appActivity, appWaitPackage, appWaitActivity);
	}
	
	/**
	 * 获取当前 activity,可用于断言是否跳转到预期的activity
	 * (只能在 Android上使用)
	 * @author aihui
	 */
	public String getCurrendActivity_AND(){
		return ((AndroidDriver) driver).currentActivity();
	}
	
	/**
	 * 打开下拉通知栏(只能在 android 上使用)
	 * @author aihui
	 */
	public static void openNotifications_AND(){
		((AndroidDriver<WebElement>) driver).openNotifications();;
	}
	
	/**
	 * 根据bundleId来判断该应用是否已经安装
	 * @author aihui
	 * @param bundleId
	 * @return True if app is installed, false otherwise
	 */
	public boolean isAppInstalled(String bundleId){
		return driver.isAppInstalled(bundleId);
	}

	/**
	 * 安装应用到设备中,appPath为应用的本地路径
	 * @author aihui
	 * @param appPath
	 */
	public static void installApp(String appPath){
		driver.installApp(appPath);
	}
	
	/**
	 * 从设备中卸载一个应用,bundleId在android中代表的是包名,而在iOS中有专门的bundleId号
	 * @author aihui
	 * @param bundleId
	 */
	public static void removeApp(String bundleId){
		driver.removeApp(bundleId);
	}
	
	/**
	 * 模拟iOS设备摇晃 (只能在iOS上使用)
	 * @author aihui
	 */
	public static void shake_IOS(){
		((IOSDriver<WebElement>) driver).shake();
	}
	
	/**
	 * 关闭应用,其实就是按Home键把应用置于后台
	 * @author aihui
	 */
	public static void closeApp(){
		driver.closeApp();
	}
	
	/**
	 * 利用ios中的uiautomation中的属性来获取控件对象
	 * @author aihui
	 * @return WebElement
	 */
	public static WebElement getElementByUIA_IOS(String using){
		return ((IOSDriver) driver).findElementByIosUIAutomation(using);
	}
		
	/**
	 * 利用ios中的uiautomation中的属性来获取控件列表(多个控件对象)
	 * @author aihui
	 * @return List<WebElement> 
	 */
	public static List<WebElement> getElementsByUIA_IOS(String using){
		return ((IOSDriver<WebElement>) driver).findElementsByIosUIAutomation(using);
	}
	
	/**
	 * 利用Andriod中的uiautomator中的属性来获取控件对象
	 * @author aihui
	 * @return WebElement
	 */
	public static WebElement getElementByUIA_AND(String using){
		return ((AndroidDriver<WebElement>) driver).findElementByAndroidUIAutomator(using);
	}
		
	/**
	 * 利用Andriod中的uiautomator中的属性来获取控件列表(多个控件对象)
	 * @author aihui
	 * @return List<WebElement> 
	 */
	public static List<WebElement> getElementsByUIA_AND(String using){
		return ((AndroidDriver<WebElement>) driver).findElementsByAndroidUIAutomator(using);
	}
	
	/**
	 * @author aihui
	 * @return List<WebElement> 
	 */
	public static WebElement getElementByAccessibilityId(String using){
		return driver.findElementByAccessibilityId(using);
	}
	
	/**
	 * @author aihui
	 * @return List<WebElement> 
	 */
	public static List<WebElement> getElementsByAccessibilityId(String using){
		return driver.findElementsByAccessibilityId(using);
	}
	
	/**
	 * 执行一个touch动作,该touch动作是由TouchAction封装的
	 * @author aihui
	 */
	public static void performTouchAction(TouchAction touchAction){
		driver.performTouchAction(touchAction);
	}
	
	/**
	 * 执行多步touch动作,由MultiTouchAction封装的多步操作
	 * @author aihui
	 */
	public static void performMultiTouchAction(MultiTouchAction multiAction){
		driver.performMultiTouchAction(multiAction);
	}
		
	/**
	 * 设置屏幕横屏(LANDSCAPE(横向)) 
	 * @author aihui
	 */
	public static void setScreenLANDSCAPE(){
		driver.rotate(ScreenOrientation.LANDSCAPE);
	}
	
	/**
	 * 设置屏幕竖屏(PORTRAIT(纵向))
	 * @author aihui
	 */
	public static void setScreenPORTRAIT(){
		driver.rotate(ScreenOrientation.PORTRAIT);
	}
	
	/**
	 * 获取当前屏幕的方向
	 * @author aihui
	 */
	public ScreenOrientation getOrientation(){
		return driver.getOrientation();
	}
	
	/**
	 * 滚动到某个text属性为指定的字符串的控件
	 * only working when android.widget.ListView have single text in it 
	 * and it fails when multiple text is present in each row of listView
	 * @author aihui
	 * @param text
	 *//*
	public static void scrollTo(String text){
		driver.scrollTo(text);
	}
	
	*//**
	 * 滚动到某个text属性包含传入的字符串的控件
	 * @author aihui
	 * @param text
	 *//*
	public static void scrollToExact(String text){
		driver.scrollToExact(text);
	}*/
		
	/**
	 * 关闭Appium Driver
	 * @author aihui
	 */
	public static void closeDriver(){
		driver.close();
	}		
		
	/**
	 * 启动应用
	 * 根据服务关键字 (desired capabilities) 启动会话 (session) 
	 * 请注意这必须在设定 autoLaunch=false 关键字时才能生效。这不是用于启动指定的 app/activities 
	 * 可以使用 start_activity 做到这个效果。这是用来继续进行使用了 autoLaunch=false 关键字时的初始化 (Launch)流程的。
	 * @author aihui
	 */
	public static void launchApp(){
		driver.launchApp();
	}
	
	/**
	 * 应用重置(相当于卸载重装应用)
	 * @author aihui
	 */
	public static void resetApp(){
		driver.resetApp();
	}
	
	/**
	 * 列出所有可用上下文集合
	 * context可以理解为可进入的窗口,例如:对于原生应用,可用的context和默认context均为NATIVE_APP
	 * @author aihui
	 */
	public static Set<String> getAllContexts(){
		return driver.getContextHandles();
	}
	
	/**
	 * 列出当前上下文
	 * @author aihui
	 */
	public String getCurrentContext(){
		return driver.getContext();
	}
	
	/**
	 * 将上下文切换到默认上下文(设置上下文)
	 * @author aihui
	 * @param name
	 */
	public static void switchToContext(String name){
		 driver.context(name);
	}
	
	/**
	 * 4.3以上才支持在android模式下切换到webview, 如果是之前的版本, 需要使用selendroid模式
	 * http://testerhome.com/topics/852
	 * 获取所有可用上下文,判断是否存在"WEBVIEW",存在则切换至WEBVIEW,且返回true,反之则返回false
	 * @author aihui
	 * @param name
	 */
	public boolean switchToWEBVIEW(){
		Set<String> contextNames = getAllContexts();
		for (String contextName : contextNames){
			if (contextName.contains("WEBVIEW")){
				switchToContext(contextName);
				return true;
			}
		}
		return false;
	}
		
	/**
	 * 获取所有定义的字符串,从App默认系统语言(Strings.xml)
	 * Get all defined Strings from an app for the default language
	 * @author aihui
	 */
	public Map<String, String> getAppStringMap(){
		 return driver.getAppStringMap();
	}
	
	/**
	 * 获取所有定义的字符串,从App指定语言(Strings.xml)
	 * Get all defined Strings from an app for the specified language
	 * @author aihui
	 */
	public Map<String, String> getAppStrings(String language){
		return driver.getAppStringMap(language);
	}
	
	/**
	 * 获取所有定义的字符串,从指定语言和文件名称
	 * Get all defined Strings from an app for the specified language and strings filename.
	 * @author aihui
	 */
	public Map<String, String> getAppStrings(String language, String stringFile){
		return driver.getAppStringMap(language,stringFile);
	}
	
	
	/**
	 * 按下某个按键,具体哪个按键由key值决定,key值定义在AndroidKeyCode类中(只能在 Android上使用)
	 * Send a key event to the device.
	 * @author aihui
	 * @param keyEvent=(AndroidKeyCode.HOME......)
	 * @param keyEvent=(AndroidKeyCode.HOME......)
	 *   a-z->29-54
	 *   0-9->7-16
	 *   CALL = 5
	 *   ENDCALL = 6
	 *   BACK = 4;
	 *   BACKSPACE = 67;
	 *   DEL = 67;
	 *   ENTER = 66;
	 *   HOME = 3;
	 *   MENU = 82;
	 *   SETTINGS = 176;
	 *   SPACE = 62;  		                 
	 */
	public static void pressKey_AND(int keyEvent){
		((AndroidDriver) driver).pressKeyCode(keyEvent);
	}
	
	/**
	 * 按下某个按键的同时按下附加键（Ctrl/Alt/Shift等,具体是哪些按键,由key值(AndroidKeyCode类中定义)和metastate(AndroidKeyMetastate类中定义)决定
	 * (只能在 Android上使用)
	 * Send a key event along with an Android metastate to an Android device. 
	 * Metastates are things like *shift* to get uppercase characters.
	 * @author aihui
	 * @param keyEvent=(AndroidKeyCode.HOME......)
	 *   a-z->29-54
	 *   0-9->7-16
	 *   CALL = 5
	 *   ENDCALL = 6
	 *   BACK = 4;
	 *   BACKSPACE = 67;
	 *   DEL = 67;
	 *   ENTER = 66;
	 *   HOME = 3;
	 *   MENU = 82;
	 *   SETTINGS = 176;
	 *   SPACE = 62;  		                 
	 */
	public static void pressKey_AND(int key, Integer metastate){
		((AndroidDriver) driver).pressKeyCode(key, metastate);
	}
	
	
	/**
	 * 长按某个按键,具体哪个按键由key值决定,key值定义在AndroidKeyCode类中(只能在 Android上使用)
	 * Send a long key event to the device.
	 * @author aihui
	 * @param keyEvent=(AndroidKeyCode.HOME......)
	 *   a-z->29-54
	 *   0-9->7-16
	 *   CALL = 5
	 *   ENDCALL = 6
	 *   BACK = 4;
	 *   BACKSPACE = 67;
	 *   DEL = 67;
	 *   ENTER = 66;
	 *   HOME = 3;
	 *   MENU = 82;
	 *   SETTINGS = 176;
	 *   SPACE = 62;  		                 
	 */
	public static void longPressKey_AND(int keyEvent){
		((AndroidDriver) driver).longPressKeyCode(keyEvent);
	}
	
	/**
	 * 长按某个按键的同时按下附加键（Ctrl/Alt/Shift等,具体是哪些按键,由key值(AndroidKeyCode类中定义)和metastate(AndroidKeyMetastate类中定义)决定
	 * (只能在 Android上使用)
	 * Send a long key event along with an Android metastate to an Android device. 
	 * Metastates are things like *shift* to get uppercase characters.
	 * @author aihui
	 * @param keyEvent=(AndroidKeyCode.HOME......)
	 *   a-z->29-54
	 *   0-9->7-16
	 *   CALL = 5
	 *   ENDCALL = 6
	 *   BACK = 4;
	 *   BACKSPACE = 67;
	 *   DEL = 67;
	 *   ENTER = 66;
	 *   HOME = 3;
	 *   MENU = 82;
	 *   SETTINGS = 176;
	 *   SPACE = 62;  		                 
	 */
	public static void longPressKey_AND(int key, Integer metastate){
		((AndroidDriver) driver).longPressKeyCode(key, metastate);
	}
	
			
	/**
	 * 模拟用户滑动
	 * 从(startx,starty)滑到(endx,endy),分duration步滑,每一步用时是5毫秒
	 * (75, 500, 75, 0, (int) 0.8)
	 * @author aihui
	 * @param int startx, int starty, int endx, int endy, int duration
	 */
	public static void swipe(int startx, int starty, int endx, int endy, int duration){
		driver.swipe(startx, starty, endx, endy,duration);
	}

	/**
     * This Method for swipe up
     * 
     * @author hyzhao
     * @param during 
     */
	public static void swipeToUp(int during) {
		int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width / 2, height * 3 / 4, width / 2, height / 4, during);
	}
	
	 /**
     * This Method for swipe down
     * 
     * @author hyzhao
     * @param during
     */
    public static void swipeToDown(int during) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width / 2, height / 4, width / 2, height * 3 / 4, during);
    }

    /**
     * This Method for swipe Left
     * 
     * @author hyzhao
     * @param during
     */
    public static void swipeToLeft(int during) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width * 3 / 4, height / 2, width / 4, height / 2, during);
    }

    /**
     * This Method for swipe Right
     * 
     * @author hyzhao
     * @param during
     */
    public static void swipeToRight(int during) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width / 4, height / 2, width * 3 / 4, height / 2, during);
    }
	
    public static void failCase(String string) {
    	Logger.log("FAIL：" + string +"，用例执行失败，请检查！");
    }
    
    public static void successCase() {
    	Logger.log("SUCCESS：用例执行成功！");
    }
	/**
	 * 从设备中拉取文件,即将设备上的文件pull到本地硬盘上
	 * String remotePath = "/data/local/tmp/file.txt";
	 * driver.pullFile("Library/AddressBook/AddressBook.sqlitedb");
	 * remotePath - On Android and iOS, this is either the path to the file (relative to the root of the app's file system). On iOS only,
	 * if path starts with /AppName.app, which will be replaced with the application's .app directory
	 * @author aihui
	 * @param remotePath
	 */
	public static void pullFile(String remotePath){
		driver.pullFile(remotePath);	
	}
	
	/**
	 * 将设备及模拟器上的文件夹拉到本地硬盘上,注:无法应用在iOS真实设备上,但可以作用在模拟器上
	 * Pull a folder from the simulator/device. Does not work on iOS Real Devices, but works on simulators
	 * 
	 * String remotePath = "/data/local/tmp/file.txt";
	 * remotePath - On Android and iOS, this is either the path to the file (relative to the root of the app's file system). On iOS only,
	 * if path starts with /AppName.app, which will be replaced with the application's .app directory
	 * @author aihui
	 * @param remotePath
	 */
	public static void pullFolder(String remotePath){
		driver.pullFolder(remotePath);	
	}
	
	/**
	 * 将base64编码数据作为文件保存到远程设备上,也可以理解为把本地文件push到设备上
	 * Saves base64 encoded data as a file on the remote mobile device.
	 * byte[] base64Data = Base64.encodeBase64("some data for the file".getBytes());
	   String remotePath = "/data/local/tmp/file.txt";
	 * @author aihui
	 * @param remotePath
	 *        Path to file to write data to on remote device
	 * @param base64Data
	 *        Base64 encoded byte array of data to write to remote device
	 */
	public static void pushFile_AND(String remotePath, byte[] base64Data){
		((AndroidDriver) driver).pushFile(remotePath, base64Data);
	}
	
	/**
	 * 将为文件保存到远程设备上,也可以理解为把本地文件push到设备上
	 * Saves given file as a file on the remote mobile device.
	 * File file = new File("C:\eclipse\img1.jpg");
	   String remotePath = "/data/local/tmp/file.txt";
	 * @author aihui
	 * @param remotePath
	 *        Path to file to write data to on remote device
	 * @param file
	 *        is a file to write to remote device
	 * @throws IOException 
	 */
	public static void pushFile_AND(String remotePath, File file) throws IOException{
		((AndroidDriver) driver).pushFile(remotePath, file);
	}
	
	
	
	public static void quit(){
		driver.quit();
	}
	
	/**
	 * 获取设备网络状态(只能在 android上使用)
	 * Connection object will let you inspect the status of None, AirplaneMode, Wifi, Data and All connections.
	 * @author aihui
	 */
	public Connection getConnection_AND(){
		Connection status = ((AndroidDriver) driver).getConnection();
		return status;
	}
	
	/**
	 * 设置设备网络状态(只能在 android上使用)
	 * 设置手机的网络连接状态,可以开关飞行模式,wifi,数据流量等.
	 * Eg:Connection.AIRPLANE,Connection.DATA,Connection.NONE,Connection.ALL,Connection.WIFI 设置各个网络连接的状态.
	 * @author aihui
	 */
	public static void setConnection_AND(Connection connection){
		((AndroidDriver) driver).setConnection(connection);;
	}
	
	
	/**
	 * 获取测试覆盖率数据(只能在 android上使用)
	 * Demo: driver.end_test_coverage(intent='com.example.pkg.END_EMMA', path='/mnt/sdcard/coverage.ec')
	 * http://appium.io/slate/en/v1.0.0/
	 * @author aihui
	 * @param intent,intent to broadcast
	 * @param path,path to .ec file()         
	 */	
	public static void getTestCoverage_AND(String intent, String path){
		((AndroidDriver) driver).endTestCoverage(intent,path);
	}
	

	
	/**
	 * 截图
	 * @author AiHui
	 */
	public static void screenShot(){
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss");
		screenShot(df.format(new Date()).toString());	
	}
	
	/**
	 * 指定名称截图
	 * @author AiHui
	 */
	public static void screenShot(String name){
		String path = System.getProperty("user.dir")+System.getProperty("ScreenShotLocation");
		File file = new File(path);
		
		if(!file.exists()){
			file.mkdir();
		}
		File screenShotFile = driver.getScreenshotAs(OutputType.FILE);
		try {
			FileUtils.copyFile(screenShotFile, new File(path +"/"+ name + ".jpg"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 将当前线程阻塞指定的时间
	 * @author aihui
	 * @param time
	 */
	public static void delay(long time) {
		try {
			Thread.sleep(time * 1000);
		} catch (Exception e) {
		}
	}
	
	/**
	 * 最后介绍AppiumDriver的getPageSource函数,
	 * 可以把当前页面的元素以XML的方式打印出来,
	 * 建议大家在找不到webview的相应属性的时候就调用该函数来慢慢查找了
	 * http://blog.csdn.net/zhubaitian/article/details/39754041
	 * @author AiHui
	 * @return pageSource
	 */
	public String getPageSource(){
		return driver.getPageSource();
	}
		
	/**
	 * @see org.openqa.selenium.remote.CapabilityType
	 * @author aihui
	 * @param capabilityName The capability to return.
	 * @return The value, or null if not set.
	 */
	public String getCapability(String capabilityName){
		return driver.getCapabilities().getCapability(capabilityName).toString();
	}

	/**
	 * Get settings stored for this test session It's probably better to use a
	 * convenience function, rather than use this function directly. Try finding
	 * the method for the specific setting you want to read
	 * @return JsonObject, a straight-up hash of settings
	 */
	public JsonObject getSettings(){
		return driver.getSettings();
	}
	
	/**
	 * @author aihui
	 * @return URL Object
	 * 一个URL对象可以表示一个网络资源。程序利用URL对象能实现Internet寻址、网络资源的定位连接、在客户机与服务器之间直接访问等
	 */
	public URL getRemoteAddress(){
		return driver.getRemoteAddress();
	} 
	
	
	
	//(以下方法,主要适用于webview操作,对于原生APP控件操作不适应)
	/**
	 * @author aihui
	 * Represents the physical location of the browser.
	 * (主要适用于webview操作,对于原生APP控件操作不适应)
	 */
	public org.openqa.selenium.html5.Location getLocation(){
		return  driver.location();
	}
	
	/**
	 * 获取页面标题
	 * (主要适用于webview操作,对于原生APP控件操作不适应)
	 * @author aihui
	 * @return title
	 */
	public String getTitle(){
		return driver.getTitle();
	}
	
	/**
	 * 打开指定地址页面(且在指定的pageLoadTimeOut时间内检查页面是否加载完毕)
	 * (主要适用于webview操作,对于原生APP控件操作不适应)
	 * @param url
	 * @author aihui
	 */
	public static void open(String url){
		driver.get(url);
	}
	
	/**
	 * 获取当前页面url
	 * (主要适用于webview操作,对于原生APP控件操作不适应)
	 * @author aihui
	 * @return url
	 */
	public String getCurrentUrl(){
		return driver.getCurrentUrl();
	}
	
	
	 /**
     * This Method for swipe Left
     * 
     * @author hyzhao
     * @param during
     */
    public static void shopDetailPageSwipeToLeft(int during) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width * 3 / 4, height * 2 / 3, width / 4, height * 2 / 3, during);
    }

    /**
     * This Method for swipe Right
     * 
     * @author hyzhao
     * @param during
     */
    public static void shopDetailPageSwipeToRight(int during) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        driver.swipe(width / 4, height * 2 / 3, width * 3 / 4, height * 2 / 3, during);
    }
	
	/* 以下API部分未完全实现且暂时未用到,可参考实际情况查询扩充
	   complexFind()
	   ignoreUnimportantViews()
	   toggleLocationServices()
	   driver.execute(driverCommand, parameters)
	   driver.executeAsyncScript(script, args);
	   driver.executeScript(script, args);
	   driver.getExecuteMethod();
	 */
}
